import api from '../api/api.js';
import os from '../os.js';

/**
 * 激励视频广告
 */
export class RewardedVideoAd {
  // 广告
  ad = null;
  // 广告id
  adUnitId = '';
  // 当前广告配置
  currenAdconf = null;
  // 当前索引
  currentIndex = 0;
  // 是否成功显示
  isSuccesShow = false;
  // 计时对象id
  timeObj = null;
  // 计秒
  second = 0;
  // 超时对象id
  loadTimerId = null;

  // 传入配置
  options = {
    // 广告配置列表
    adConfList: false,
    // 配置变化时触发
    onAdConfChange: null,
    // 加载成功触发
    onLoad: null,
    // 关闭广告触发
    onClose: null,
    // 广告出错触发
    onError: null,
    // 广告显示触发
    onShow: null
  };

  constructor(options) {

    Object.assign(this.options, options);

    if (!this.options.onAdConfChange) {
      throw new Error('options.onAdConfChange is required');
    }

    if (!this.options.onLoad) {
      throw new Error('options.onLoad is required');
    }

    if (!this.options.onClose) {
      throw new Error('options.onClose is required');
    }

    if (!this.options.onError) {
      throw new Error('options.onError is required');
    }

    if (!this.options.onShow) {
      throw new Error('options.onShow is required');
    }

    if (this.options.adConfList === false) {
      this.getAdvertConfig()
      return;
    }

    this._changeCurrentAdConf(this.currentIndex);

    this._init();
  }

  async _init() {
    if (this.adUnitId === '') {
      this.options.onError({errCode: 158802, errMsg: "The adUnitId is invalid"});
      return;
    }

    // 创建广告
    console.info('adUnitId', this.adUnitId);
    this.ad = os.createRewardedVideoAd({
      adUnitId: this.adUnitId
    });

    os.showLoading({title: '请稍候...', mask: true});

    this.clearLoadTimeObj();
    const _this = this;
    this.loadTimerId = setTimeout(function(){
      os.hideLoading({});
      _this.loadTimerId = null;
      _this.options.onError({errCode: -2, errMsg: "请勿频繁操作"})
    }, 15000);

    this.options.onLoad({type: 'reg'});

    // 绑定广告
    this.bindAdListener();

    // 显示广告
    this.ad.show().then(() => {
      // console.log('Ad Succes:', '广告显示成功');
      os.hideLoading({});
      this.isSuccesShow = true;
      this.createTimeObj();
      this.clearLoadTimeObj();
      this.options.onShow();
    }).catch((err) => {
      // 可以手动加载一次
      this.ad.load().then(() => {
        // 加载成功后需要再显示广告
        return this.ad.show().then(() => {
          // console.log('Ad Succes:', '广告显示成功');
          os.hideLoading({});
          this.isSuccesShow = true;
          this.createTimeObj();
          this.clearLoadTimeObj();
          this.options.onShow();
        }).catch((err) => {
          console.warn('Ad show:', err);
          os.hideLoading({});
          this.isSuccesShow = false;
          // return this.options.onError(err);
        });

      }).catch((err) => {
        console.warn('Ad load:', err);
        os.hideLoading({});
        this.isSuccesShow = false;
        // return this.options.onError(err);
      });
    });
  }

  show(){
    if(this.isSuccesShow == false){
      this.currentIndex += 1;
    }
    this._changeCurrentAdConf(this.currentIndex);
    this._init();
  }

  bindAdListener(){
    this.ad.onLoad(() => {
      this.options.onLoad({type: 'success'});
      // console.log('Ad onLoad:','拉取广告素材成功');
    });

    this.ad.onClose((res) => {
      os.hideLoading({});
      res.second = this.second;
      this.clearTimeObj();
      this.clearLoadTimeObj();
      // console.log('Ad onClose: 已关闭广告', res);
      this.options.onClose(res);
    });
    
    this.ad.onError(error => {
      this.isSuccesShow = false;
      this.options.onError(error);
    });
  }

  destroy(){
    if(this.ad === null){
      return;
    }
    this.clearTimeObj();
    this.clearLoadTimeObj();
    this.unBindAdListener();
    this.ad.destroy().then(() => {
      // console.info('Ad destroy: 销毁成功');
    }).catch((err) => {
      console.warn('Ad destroy:', err);
    });
  }

  unBindAdListener(){

    this.ad.offLoad(() => {
      console.info("解除绑定 load 事件的监听器");
    });

    this.ad.offError(() => {
      console.info("解除绑定 error 事件的监听器");
    });

    this.ad.offClose(() => {
      console.info("解除绑定 close 事件的监听器");
    });
  }

  createTimeObj(){
    const that = this;

    this.clearTimeObj();

    this.timeObj = setInterval(function(){
      that.second += 1;
    }, 1000);
  }

  getAdvertConfig() {
    api.getAdvertConfig(1, {showErr: false}).then(res => {
      if (res.code == 200) {
        const strategy = res.data?.advert_strategy || [];
        if (strategy.length > 0) {
          this.options.onAdConfChange({type: 1, data: res.data});
          this.options.adConfList = res.data;
          this._changeCurrentAdConf(this.currentIndex);
          this._init();
          return;
        }
      }
      this.options.onError({errCode: -1, errMsg: "No advertising configuration"});
    }).catch(err => {
      this.options.onError({errCode: -1, errMsg: "No advertising configuration"});
    });
  }

  clearTimeObj(){
    if(this.timeObj === null){
      return;
    }

    clearInterval(this.timeObj);
    this.second = 0;
    this.timeObj = null;
  }

  clearLoadTimeObj(){
    if(this.loadTimerId === null){
      return;
    }
    clearTimeout(this.loadTimerId);
    this.loadTimerId = null;
  }

  _changeCurrentAdConf(targetIndex) {

    if (this.options.adConfList === false) {
      this.options.onError({errCode: -1, errMsg: "No advertising configuration"});
      return;
    }

    // console.log(this.options.adConfList);
    const strategy = this.options.adConfList.advert_strategy;
    
    if ((strategy.length - 1) < targetIndex) {
      targetIndex = 0;
    }

    this.currentIndex = targetIndex;
    this.currenAdconf = strategy[targetIndex];
    this.adUnitId = this.currenAdconf.source_app_key;
    this.options.onAdConfChange({type: 0, data: this.currenAdconf});
  }

}
